package com.xinsoft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.common.exception.BDException;
import com.xinsoft.constant.Const;
import com.xinsoft.entity.dto.CusPatrolDetailDTO;
import com.xinsoft.entity.dto.CusPatrolPlanDTO;
import com.xinsoft.entity.dto.CusPatrolPlanParam;
import com.xinsoft.entity.po.*;
import com.xinsoft.entity.vo.CusPatrolPlanDetailVo;
import com.xinsoft.entity.vo.CusPatrolPlanDeviceVo;
import com.xinsoft.entity.vo.CusPatrolPlanVo;
import com.xinsoft.job.PatrolPlanJob;
import com.xinsoft.mapper.CusPatrolPlanMapper;
import com.xinsoft.service.*;
import com.xinsoft.utils.QuartzUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author lijie
 * @description 针对表【cus_patrol_plan(巡检计划)】的数据库操作Service实现
 * @createDate 2023-06-20 13:49:29
 */
@Service
@Slf4j
public class CusPatrolPlanServiceImpl extends ServiceImpl<CusPatrolPlanMapper, CusPatrolPlan>
        implements CusPatrolPlanService {

    @Resource
    CusPatrolPlanMapper cusPatrolPlanMapper;

    @Resource
    CusPatrolPlanDetailService detailService;

    @Resource
    CusPatrolDetailService patrolDetailService;

    @Resource
    CusPatrolService patrolService;

    @Resource
    SysUserService userService;

    @Resource
    SysDeptService deptService;

    @Resource
    SysDocumentNumService sysDocumentNumService;

    @Override
    public void tempSave(CusPatrolPlanDTO cusPatrolPlanDTO) {
        // 暂存有新增和编辑场景
        if (cusPatrolPlanDTO.getId() == null) {
            cusPatrolPlanDTO.setPlanStatus(Const.PLAN_STATUS_WAIT);
            // 更新计划单号
            sysDocumentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.PATROL_PLAN_DOCUMENT);
            cusPatrolPlanMapper.insert(cusPatrolPlanDTO);
            // 解析计划设备项目关系表
            if (cusPatrolPlanDTO.getDeviceDTOList() != null) {
                this.dealList(cusPatrolPlanDTO);
            } else {
                throw new BDException("操作失败，不包含设备巡检项目集合！");
            }
        } else {
            // 解析计划设备项目关系表
            cusPatrolPlanDTO.setPlanStatus(Const.PLAN_STATUS_WAIT);
            if (cusPatrolPlanDTO.getDeviceDTOList() != null) {
                detailService.remove(new QueryWrapper<CusPatrolPlanDetail>().eq("patrol_plan_id", cusPatrolPlanDTO.getId()));
                this.dealList(cusPatrolPlanDTO);
            } else {
                throw new BDException("操作失败，不包含设备项目集合！");
            }
            cusPatrolPlanMapper.updateById(cusPatrolPlanDTO);
        }
    }

    public void dealList(CusPatrolPlanDTO cusPatrolPlanDTO) {
        for (int i = 0; i < cusPatrolPlanDTO.getDeviceDTOList().size(); i++) {
            for (int j = 0; j < cusPatrolPlanDTO.getDeviceDTOList().get(i).getPatrolDetailDTOList().size(); j++) {
                CusPatrolDetailDTO cusPatrolDetailDTO = cusPatrolPlanDTO.getDeviceDTOList().get(i).getPatrolDetailDTOList().get(j);
                CusPatrolPlanDetail detail = new CusPatrolPlanDetail();
                detail.setPatrolPlanId(cusPatrolPlanDTO.getId());
                detail.setDeviceId(cusPatrolPlanDTO.getDeviceDTOList().get(i).getDeviceId());
                detail.setPatrolStandardId(cusPatrolDetailDTO.getPatrolStandardId());
                BeanUtil.copyProperties(cusPatrolDetailDTO, detail);
                // 乘积出来具体的关系条数
                detailService.save(detail);
            }
        }
    }

    @Override
    public CusPatrolPlanVo getByInfoById(Integer id) {
        CusPatrolPlan cusPatrolPlan = cusPatrolPlanMapper.selectById(id);
        // 组装负责人姓名，电话，部门
        SysUser user = userService.getById(cusPatrolPlan.getPatrolPersonId());
        if (user != null) {
            cusPatrolPlan.setPlanPersonName(user.getRealName());
            cusPatrolPlan.setPlanPersonDept(deptService.getById(user.getDeptId()).getDeptName());
            cusPatrolPlan.setPlanPersonTel(user.getMobile());
        }
        CusPatrolPlanVo cusPatrolPlanVo = new CusPatrolPlanVo();
        BeanUtil.copyProperties(cusPatrolPlan, cusPatrolPlanVo);
        // 组装巡检明细
        List<CusPatrolPlanDeviceVo> patrolDeviceVoList = cusPatrolPlanMapper.getDeviceListByPatrolId(id);
        if (patrolDeviceVoList.size() > 0) {
            for (int i = 0; i < patrolDeviceVoList.size(); i++) {
                CusPatrolPlanDeviceVo cusPatrolDeviceVo = patrolDeviceVoList.get(i);
                List<CusPatrolPlanDetailVo> detailVoList = cusPatrolPlanMapper.getDetailListByDeviceId(cusPatrolDeviceVo.getDeviceId(), id);
                if (detailVoList.size() > 0) {
                    cusPatrolDeviceVo.setCusPatrolPlanDetailVoList(detailVoList);
                }
            }
            cusPatrolPlanVo.setPatrolPlanDeviceVos(patrolDeviceVoList);
        }
        return cusPatrolPlanVo;
    }

    @Override
    public void submit(CusPatrolPlanDTO cusPatrolPlanDTO) {
        // 提交场景
        if (cusPatrolPlanDTO.getId() == null) {
            cusPatrolPlanDTO.setPlanStatus(Const.PLAN_STATUS_NORMAL);
            sysDocumentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.PATROL_PLAN_DOCUMENT);
            cusPatrolPlanMapper.insert(cusPatrolPlanDTO);
            // 解析计划设备项目关系表
            if (cusPatrolPlanDTO.getDeviceDTOList() != null) {
                this.dealList(cusPatrolPlanDTO);
            } else {
                throw new BDException("操作失败，不包含设备巡检项目集合！");
            }
        } else {
            cusPatrolPlanDTO.setPlanStatus(Const.PLAN_STATUS_NORMAL);
            // 解析计划设备项目关系表
            if (cusPatrolPlanDTO.getDeviceDTOList() != null) {
                detailService.remove(new QueryWrapper<CusPatrolPlanDetail>().eq("patrol_plan_id", cusPatrolPlanDTO.getId()));
                this.dealList(cusPatrolPlanDTO);
            } else {
                throw new BDException("操作失败，不包含设备项目集合！");
            }
            cusPatrolPlanMapper.updateById(cusPatrolPlanDTO);
        }
        // 根据提交的计划去创建定时任务测试
        QuartzUtil.addJobTask(PatrolPlanJob.class, cusPatrolPlanDTO.getPlanStartTime(), cusPatrolPlanDTO.getPlanEndTime(), cusPatrolPlanDTO.getIntervalHour(), cusPatrolPlanDTO.getId());
    }

    @Override
    public void planToTask(Integer planId) {
        // 检索最新的计划状态，如果已禁用 或者已删除，不允许继续执行
        CusPatrolPlan cusPatrolPlan = cusPatrolPlanMapper.selectById(planId);
        if (cusPatrolPlan == null || cusPatrolPlan.getDoAble().equals(Const.AUDIT_STATUS_BAN)) {
            log.info("该巡检计划已禁用或删除，无需生成执行，计划id：" + planId);
        }
        // 生成执行本体
        CusPatrol cusPatrol = new CusPatrol();
        cusPatrol.setPatrolPlanId(planId);
        String code = sysDocumentNumService.getSysDocumentNumByDocumentId(Const.DOCUMENT_ID.PATROL_ORDER_DOCUMENT);
        sysDocumentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.PATROL_ORDER_DOCUMENT);
        cusPatrol.setPatrolNum(code);
        cusPatrol.setPatrolName(cusPatrolPlan.getPlanName() + code);
        BeanUtil.copyProperties(cusPatrolPlan, cusPatrol);
        cusPatrol.setPatrolStartTime(new Date());
        cusPatrol.setCompleteTime(DateUtil.offsetHour(new Date(), cusPatrolPlan.getIntervalHour()));
        cusPatrol.setPatrolStatus(Const.PLAN_STATUS_NORMAL);
        patrolService.save(cusPatrol);
        // 根据计划明细把执行明细也生成
        List<CusPatrolPlanDetail> detailList = detailService.list(new QueryWrapper<CusPatrolPlanDetail>().eq("patrol_plan_id", cusPatrolPlan.getId()));
        // 计算规则：这条巡检明细的计划开始时间 + 间隔时间 正好在这个小时的维度内
        if (detailList.size() > 0) {
            for (int j = 0; j < detailList.size(); j++) {
                CusPatrolPlanDetail detail = detailList.get(j);
                CusPatrolDetail patrolDetail = new CusPatrolDetail();
                patrolDetail.setPatrolId(cusPatrol.getId());
                BeanUtil.copyProperties(detail, patrolDetail);
                patrolDetailService.save(patrolDetail);
            }
        }
    }

    @Override
    public Object findPageListByParam(CusPatrolPlanParam param) {
        //分页
        Page<CusPatrolPlan> page = new Page<CusPatrolPlan>(param.getCurrentPage(), param.getPageSize());
        IPage<CusPatrolPlan> resultPage = cusPatrolPlanMapper.findListByParam(page, param);
        //返回值
        return resultPage;
    }
}




